﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Windows.Forms;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using System.Text.RegularExpressions;
using System.Threading;
using Mimoza.GUI;
using Mimoza.Common;
using Microsoft.Win32;


namespace Mimoza.Plugins.DisplaySettings
{
    public partial class DisplaySettingsConfigPage : UserControl, Mimoza.GUI.IWizardPage
    {
        private string labelText;
        private const double stdRatio = 1.4;
        private IEnumerable<DisplayResolution> m_resolutionList;
        private DisplayResolution m_data;
        private int m_freq = 60;
        private ColorDepth m_colorDepth = ColorDepth.Color16Bit;

        private List<int> listOfFreq = new List<int>();
        private List<ColorDepth> listOfColor = new List<ColorDepth>();

        #region IWizardPage Members
        private IWizard m_wizard;
        private bool m_IsConfigured = true;

        protected void RaiseOnPageModified()
        {
            PageEvent handler = OnPageModified;

            if (handler != null)
            {
                handler(this);
            }
        }

        public void Init(Mimoza.GUI.IWizard wizard)
        {
            m_wizard = wizard;

            labelText = this.platform.Text;
            if (wizard.Mode != WizardMode.Wizard)
            {
                EnterPage();
            }

            this.linkLabel1.Click += new System.EventHandler(this.linkLabel1_Click);
            this.stdDisplay.CheckedChanged += new System.EventHandler(this.stdDisplay_CheckedChanged);
            this.resolutionsList.SelectedIndexChanged += new System.EventHandler(this.resolutionsList_SelectedIndexChanged);

            this.buttonTest.Enabled = false;
        }

        public void EnterPage()
        {
            this.buttonTest.Enabled = true;

            m_data = this.Wizard.UserData as DisplayResolution;
            if (m_data == null) return;

            if (m_data.Model == ModelEnum.C36SX)
            {
                this.platform.Text = labelText + Model.C36SX_DisplayName;
                InitializeList(DisplayPlatformPage.ResolutionListC36);
            }
            else if (m_data.Model == ModelEnum.L66)
            {
                this.platform.Text = labelText + Model.L66_DisplayName;
                InitializeList(DisplayPlatformPage.ResolutionListL66);

#if WindowsCE
                this.buttonTest.Enabled = true;
#endif
            }
            else if (m_data.Model == ModelEnum.LX)
            {
                this.platform.Text = labelText + Model.LX_DisplayName;
                InitializeList(DisplayPlatformPage.ResolutionListLX);
            }
            else if (m_data.Model == ModelEnum.VPC)
            {
                this.platform.Text = labelText + Model.VPC_DisplayName;
                InitializeList(DisplayPlatformPage.ResolutionListVPC);
            }
            else
            {
                //MessageBox.Show("Undefined platform :" + m_data.Model.ToString(), "Error", MessageBoxButtons.OK, MessageBoxIcon.Question, MessageBoxDefaultButton.Button1);
                throw new Exception("Undefined platform :" + m_data.Model.ToString());
            }

            if (m_data.Ratio <= stdRatio)
            {
                this.wideDisplay.Checked = false;
                this.stdDisplay.Checked = true;
            }
            else
            {
                this.wideDisplay.Checked = true;
                this.stdDisplay.Checked = false;
            }

            m_freq = m_data.Freq;
            m_colorDepth = m_data.ColorDepth;

            FillList();           
        }

        public bool Try2LeavePage(WizardPageLeavingDirection direction)
        {
            if (direction == WizardPageLeavingDirection.Back)
            {
                return true;
            }

            this.Wizard.UserData = this.resolutionsList.SelectedItem;
            return true;
        }

        public Mimoza.GUI.IWizard Wizard
        {
            get
            {
                return m_wizard;
            }
        }

        public string PageName
        {
            get { return  Resource.DisplaySettingsPageName; }
        }

        public string PageTitle
        {
            get { return Resource.DisplaySettingsPageName; }
        }

        public bool IsConfigured
        {
            get
            {
                return m_IsConfigured;
            }
            set
            {
                m_IsConfigured = value;
            }
        }

        public event Mimoza.GUI.PageEvent OnPageModified;

        #endregion

        private static int CompareDisplayResolution(DisplayResolution x, DisplayResolution y)
        { 
            if (x.Width < y.Width) return -1;
            if (x.Width == y.Width && x.Height < y.Height ) return -1;

            return 1;
        }

        private void FillList()
        {
            List<DisplayResolution> dispRes = new List<DisplayResolution>();

            listOfFreq.Clear();
            listOfColor.Clear();

            resolutionsList.Items.Clear();
            resolutionsList.DisplayMember = "DisplayText";
            if (m_resolutionList == null || m_data == null)
                return;
            
            foreach (DisplayResolution res in m_resolutionList)
            {
                if (this.stdDisplay.Checked == true && res.Ratio > stdRatio)
                {
                    continue;
                }
                else if (this.stdDisplay.Checked == false && res.Ratio <= stdRatio)
                {
                    continue;
                }

                if (!listOfFreq.Contains(res.Freq))
                {
                    listOfFreq.Add(res.Freq);
                }

                if (!listOfColor.Contains(res.ColorDepth))
                {
                    listOfColor.Add(res.ColorDepth);
                }

                if (m_freq == res.Freq && m_colorDepth == res.ColorDepth)
                {
                    if (null == m_data)
                    {
                        m_data = res;
                    }

                    res.Model = m_data.Model;
                    dispRes.Add(res);
                }
            }

            listOfFreq.Sort();
            listOfColor.Sort();
            dispRes.Sort(CompareDisplayResolution);
            int i = 0;
            foreach ( DisplayResolution res in dispRes)
            {
                resolutionsList.Items.Add(res);
                if (res.DisplayText == m_data.DisplayText)
                {
                    resolutionsList.SelectedIndex = i;
                }
                i++;
            }
        }

        public DisplaySettingsConfigPage()
        {
            InitializeComponent();
        }

        public DisplaySettingsConfigPage(IEnumerable<DisplayResolution> resolutionList)
        {
            InitializeList(resolutionList);
            InitializeComponent();
        }

        public void InitializeList(IEnumerable<DisplayResolution> resolutionList)
        {
            m_resolutionList = resolutionList;
        }

        private void stdDisplay_CheckedChanged(object sender, EventArgs e)
        {
            FillList();
            this.RaiseOnPageModified();
        }

        private void linkLabel1_Click(object sender, EventArgs e)
        {
            AdvancedSettingsForm form = new AdvancedSettingsForm();
            form.ListOfColor = listOfColor;
            form.ListOfFreq = listOfFreq;
            form.CurrentColor = m_data.ColorDepth;
            form.CurrentFreq = m_data.Freq;
            form.Location = new System.Drawing.Point(this.Parent.Parent.Location.X + (this.Size.Width-form.Size.Width)/2,this.Parent.Parent.Location.Y + (this.Size.Height-form.Size.Height)/2);

            if (form.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                m_freq = form.CurrentFreq;
                m_colorDepth = form.CurrentColor;

                FillList();
                this.RaiseOnPageModified();
            }
        }

        private void resolutionsList_SelectedIndexChanged(object sender, EventArgs e)
        {
            this.RaiseOnPageModified();
        }

        private void buttonTest_Click(object sender, EventArgs e)
        {
            Utils.TestResolution((DisplayResolution)this.resolutionsList.SelectedItem);
        }
    }
  
    public class Utils
    {
        [DllImport("Mimoza.SetDisplayMode")]
        private static extern int SetDisplayMode(Int16 width, Int16 height, Int16 colorDepth, Int16 freq);

        public static void TestResolution(DisplayResolution dispRes)
        {
            SetDisplayMode((Int16)dispRes.Width, (Int16)dispRes.Height, (Int16)dispRes.ColorDepthAsInt, (Int16)dispRes.Freq);
        }
    }
}
